﻿#include "helloword.h"
#include <QQmlEngine>
#include <QQmlContext>
#include <QQmlComponent>
#include <QQuickItem>
// CTKPluginFramework includes
#include "ctkPluginContext.h"
#include <ctkException.h>

#include "PluginInterfaces.h"

HelloWord::HelloWord(ctkPluginContext *context, QObject *parent)
    :m_context(context)
    ,m_helloManager(new HelloManager(this))
{
    startListening();
}

HelloWord::~HelloWord()
{

}

void HelloWord::TestInterface()
{
	qDebug() << "test interface";
}

void HelloWord::loadQmlWindowStatus()
{
    if (m_component->isError()) {
        qWarning() << m_component->errors();
    }
    else {
        m_selfObject = m_component->create();
    }
}

void HelloWord::initQmlWindow()
{
    auto viewer = getMainView();
    viewer->rootContext()->setContextProperty("helloManager", m_helloManager);
    if(m_selfObject == nullptr) {
        m_component = new QQmlComponent(viewer->engine(), viewer->rootObject());
        m_component->loadUrl(QUrl("qrc:/qml/helloword.qml"));
        if (m_component->isLoading())
            QObject::connect(m_component, SIGNAL(statusChanged(QQmlComponent::Status)),
                             this, SLOT(loadQmlWindowStatus()));
        else
            loadQmlWindowStatus();

        QQmlEngine::setObjectOwnership(m_selfObject, QQmlEngine::CppOwnership);
    }

    QQuickItem *item = qobject_cast<QQuickItem*>(m_selfObject);
    item->setParentItem(viewer->rootObject());
    item->setParent(viewer->engine());
    item->setVisible(true);
}

QString HelloWord::doGetSTringFromHelloword()
{
    return "test string";
}

///////////////////////////////////////////////////事件处理////////////////////////////////////////////////////////
void HelloWord::startListening(){
    ctkDictionary dic;
	// 需要和谁通信，这里将字段加入监听队列
    dic.insert(ctkEventConstants::EVENT_TOPIC, TOPIC_MAINWINDOW);
    m_context->registerService<ctkEventHandler>(this, dic);
    // CTK通讯的线程不是主UI线程,这里需要将信号发送到主界面的UI线程上来
    connect(this, &HelloWord::handleCtkEvent, this, &HelloWord::onCtkEvent, Qt::QueuedConnection);
}

void HelloWord::handleEvent(const ctkEvent& event){
    emit handleCtkEvent(event);
}

void HelloWord::onCtkEvent(const ctkEvent& event)
{
    QString eventStr = event.getProperty(PROPERTY_EVENT).toString();
    if(eventStr.contains(MAINWINDOW_LOAD)) {
        initQmlWindow();
    }
    if(eventStr.contains(MAINWINDOW_STRING)) {
        emit m_helloManager->testSignals(event.getProperty(PROPERTY_DATA).toString());
    }
}

ctkEventAdmin* HelloWord::getEventAdmin()
{
    ctkServiceReference ref;
    ctkEventAdmin *eventAdmin = nullptr;

    try {
        ref = m_context->getServiceReference<ctkEventAdmin>();
    }  catch (const ctkServiceException& e) {
        qCritical() << e.printStackTrace();
    } catch (...) {
        qCritical() << "Unknown exception.";
    }

    if (ref) {
        eventAdmin = m_context->getService<ctkEventAdmin>(ref);
        m_context->ungetService(ref);
    } else {
        qCritical() << "Get ctkEventAdmin error.";
    }

    return eventAdmin;
}

void HelloWord::postCtkEvent(const QString event, const QVariant data, const QVariant extentionData)
{
	ctkEventAdmin *eventAdmin = getEventAdmin();
    if(eventAdmin != nullptr){
        ctkDictionary dic;
        dic.insert(PROPERTY_EVENT, event);
        dic.insert(PROPERTY_DATA, data);
        dic.insert(PROPERTY_EXTENTION, extentionData);
        eventAdmin->postEvent(ctkEvent(TOPIC_HELLOWORD,dic));
    }
}
